package com.fox.domain.model;

import com.fox.domain.model.enums.OrderStatus;
import com.fox.domain.service.DiscountPolicy;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * 聚合根：Order
 * Order 是聚合根，持有一个唯一 UUID，不依赖外部框架，封装了订单的核心行为（计算总价、应用折扣、状态校验）。
 * OrderItem 作为聚合内实体，负责订单行级计算。
 * 将“业务行为”方法都放到聚合根及相关实体里，避免了“贫血模型”。
 */
public class Order {

    private final UUID id;                    // 聚合根唯一标识
    private final Long userId;                // 下单用户
    private final List<OrderItem> items;      // 订单明细
    private Money totalAmount;                // 订单总金额
    private OrderStatus status;               // 订单状态
    private final LocalDateTime createdAt;     // 下单时间

    public Order(Long userId, List<OrderItem> items) {
        if (userId == null || items == null || items.isEmpty()) {
            throw new IllegalArgumentException("用户 ID 和订单明细不能为空");
        }
        this.id = UUID.randomUUID();
        this.userId = userId;
        this.items = new ArrayList<OrderItem>(items);
        this.createdAt = LocalDateTime.now();
        this.status = OrderStatus.CREATED;
        calculateTotalAmount();
    }

    /**
     * 计算订单总金额（初始不含折扣）
     */
    private void calculateTotalAmount() {
        Money sum = new Money(new java.math.BigDecimal("0"), 
                              java.util.Currency.getInstance("CNY"));
        for (OrderItem item : items) {
            sum = sum.add(item.subtotal());
        }
        this.totalAmount = sum;
    }

    public UUID getId() {
        return id;
    }

    public Long getUserId() {
        return userId;
    }

    public List<OrderItem> getItems() {
        return Collections.unmodifiableList(items);
    }

    public Money getTotalAmount() {
        return totalAmount;
    }

    public OrderStatus getStatus() {
        return status;
    }

    public LocalDateTime getCreatedAt() {
        return createdAt;
    }

    /**
     * 业务行为：应用优惠策略
     */
    public void applyDiscount(DiscountPolicy policy) {
        if (policy == null) {
            return;
        }
        // 调用领域服务计算折扣后金额
        Money discounted = policy.calculateDiscountedAmount(this.totalAmount);
        this.totalAmount = discounted;
    }

    /**
     * 业务行为：扣减库存前置校验
     * 库存校验由应用层在调用外部服务后，再回调此方法，但仍将状态设为 PENDING_STOCK_CHECK（例子）
     */
    public void markPendingStockCheck() {
        if (this.status != OrderStatus.CREATED) {
            throw new IllegalStateException("只有 CREATED 状态才能校验库存");
        }
        this.status = OrderStatus.PENDING_STOCK_CHECK;
    }

    /**
     * 业务行为：标记支付
     */
    public void markPaid() {
        if (this.status != OrderStatus.PENDING_STOCK_CHECK && 
            this.status != OrderStatus.CREATED) {
            throw new IllegalStateException("不允许的状态流转");
        }
        this.status = OrderStatus.PAID;
    }

    // 其他业务行为：完成订单、取消订单等可按需添加
}